home *** CD-ROM | disk | FTP | other *** search
- /*
- File: WinBoot.c
-
- Contains: Hack to make the Mac boot sequence resemble
- a PC/Win95 boot sequence.
-
- Written by: Eric Traut
-
- Date: 6/25/97
-
- */
-
-
- #include <OSUtils.h>
- #include <Events.h>
- #include <Menus.h>
- #include <Quickdraw.h>
- #include <Dialogs.h>
- #include <TextEdit.h>
- #include <Devices.h>
- #include <Windows.h>
- #include <Fonts.h>
- #include <LowMem.h>
- #include <Gestalt.h>
- #include <Palettes.h>
- #include <Retrace.h>
- #include <Sound.h>
- #include <MixedMode.h>
- #include <Traps.h>
- #include <Processes.h>
- #include <QDOffscreen.h>
-
- /* Static and Global Variables */
- static GDHandle sMainDevice;
- static UInt16 sBitsPerPixel;
- static Rect sRealDeviceRect;
- static Rect sDeviceRect;
- static Ptr sRealDeviceBasePtr;
- static Ptr sDeviceBasePtr;
- static UInt32 sDeviceRowBytes;
- static UInt16 sTotalTextColumns;
- static UInt16 sTotalTextRows;
- static UInt16 sCurTextRow = 0;
- static Handle sWin95SplashScreen = NULL;
- static Handle sWin95Colors = NULL;
- static Handle sPCFont = NULL;
- static Handle sWin95BootSound = NULL;
- static UInt32 sNextStateChangeTicks;
- static UInt32 sCurrentDrawState;
- static UInt32 sCurrentDrawSubState;
- static UInt32 sMachineSpeed;
- static UInt32 sMachineMemory;
- static UInt32 sMachineType;
- static VBLTask sVBLTask;
- static QDGlobals myQd;
- static UniversalProcPtr sOriginalLaunch;
- static UniversalProcPtr sOriginalDMB;
- static UniversalProcPtr sOriginalSetEntries;
- static SInt16 sPictWidth;
- static SInt16 sPictHeight;
- static SInt16 sHScale;
- static SInt16 sVScale;
- static Boolean sLaunchPatchActive = true;
- static Boolean sDMBPatchActive = true;
- static Boolean sSetEntriesPatchActive = true;
- static Boolean sVBLRunning = true;
- static UInt32 sLastInitName = 0;
- static SndChannelPtr sSoundChannel = NULL;
-
- /* Local Functions */
- static void InitMac(void);
- static void InstallVBL(void);
- static Boolean InitScreenInfo(void);
- static void LoadResources(void);
- static void ApplyPatches(void);
- static void InstallVBL(void);
- static void DrawWin95SplashScreen(void);
- static void DrawWin95ProgressBar(UInt8 inCurStage);
- static void DrawDOSText(UInt16 inHPos, UInt16 inVPos, StringPtr inString, Boolean inInvert);
- static void VBLDrawProc(VBLTaskPtr vblTaskPtr);
- static Boolean DoMemoryTest(void);
- static void TearDownHacks(void);
- static void PlayWin95StartSound(void);
- static void GetProcessorString(Str255 outProcString);
- static void AppendPString(StringPtr ioStrA, StringPtr ioStrB);
- pascal OSErr LaunchPatchProc(LaunchPBPtr LaunchParams);
- pascal void DMBPatchProc(void);
- pascal void SetEntriesPatch(short start, short count, CSpecArray aTable);
- static Boolean HasNewInitName(Str63 outInitName);
- static void DrawNewInitName(Str63 inInitName);
- static void ScrollTextScreen(UInt16 inRows);
- static void DoBillGatesAnimation(void);
-
- /* Static Routine Descriptors */
- static RoutineDescriptor sVBLRD = BUILD_ROUTINE_DESCRIPTOR(uppVBLProcInfo, &VBLDrawProc);
- static RoutineDescriptor sLaunchRD = BUILD_ROUTINE_DESCRIPTOR(kPascalStackBased | RESULT_SIZE(kTwoByteCode) | STACK_ROUTINE_PARAMETER(1, kFourByteCode), &LaunchPatchProc);
- static RoutineDescriptor sDMBRD = BUILD_ROUTINE_DESCRIPTOR(kPascalStackBased, &DMBPatchProc);
- static RoutineDescriptor sSetEntriesRD = BUILD_ROUTINE_DESCRIPTOR(kPascalStackBased | STACK_ROUTINE_PARAMETER(1, kTwoByteCode) | STACK_ROUTINE_PARAMETER(2, kTwoByteCode) | STACK_ROUTINE_PARAMETER(3, kFourByteCode), &SetEntriesPatch);
-
- /* Constant Definitions */
- enum
- {
- kTextCellHSize = 8,
- kTextCellVSize = 16,
-
- // Drawing states
- kDrawBIOSMessage = 0,
- kDrawMemorySize,
- kDrawStartingOS,
- kDrawCDDriverText,
- kMouseDriverText,
- kBlinkCursor,
- kDrawWin95Screen,
- kAnimateWin95Screen,
-
- kProgressBarHeight = 26,
- kBillScrollAmount = 8
- };
-
- /*--------------------------------------------------------
- main
-
- Main entry point to the INIT.
- --------------------------------------------------------*/
-
- void
- main(void)
- {
- // We need to initialize the Mac toolbox first
- InitMac();
-
- // Next we'll blank the entire screen to prepare to
- // make it look like a PC screen at boot time
- if (InitScreenInfo())
- {
- // Next, we'll load our resource (fonts, PICTs, etc.
- // so they are in memory when we need them).
- LoadResources();
-
- // We need to temporarily patch out calls to QuickDraw
- // so icons and other items in the boot sequence are
- // not drawn on top of us.
- ApplyPatches();
-
- // Initialize our state
- sCurrentDrawState = kDrawBIOSMessage;
- sNextStateChangeTicks = 0;
-
- // Finally, we'll install a VBL task to complete
- // our boot sequence.
- InstallVBL();
- //TearDownHacks();
- }
- }
-
-
- /*--------------------------------------------------------
- InitMac
-
- Initializes the Mac toolbox.
- --------------------------------------------------------*/
-
- void
- InitMac(void)
- {
- long gestaltResult;
- OSErr tempErr;
-
- // Get information about the CPU (type and speed)
- tempErr = Gestalt(gestaltNativeCPUtype, &gestaltResult);
- if (tempErr == noErr)
- sMachineType = gestaltResult;
- else
- sMachineType = 0;
-
- tempErr = Gestalt('pclk', &gestaltResult);
- if (tempErr == noErr)
- sMachineSpeed = gestaltResult;
- else
- sMachineSpeed = 0;
-
- // Get information about memory (size of memory in Kb)
- (void) Gestalt(gestaltPhysicalRAMSize, &gestaltResult);
- sMachineMemory = gestaltResult / 1024L;
-
- InitGraf(&myQd.thePort);
- }
-
-
- /*--------------------------------------------------------
- InitScreenInfo
-
- Determines the bounds of the main monitor and its
- bit depth. If the depth is in the range we support,
- it blanks the screen and returns true. Else it returns
- false to indicate the INIT should just quietly do
- nothing.
- --------------------------------------------------------*/
-
- Boolean
- InitScreenInfo(void)
- {
- PixMapHandle devicePixMap;
-
- sMainDevice = GetMainDevice();
- if (sMainDevice == NULL)
- return false;
-
- devicePixMap = (**sMainDevice).gdPMap;
- if (devicePixMap == NULL)
- return false;
-
- // We currently only handle 8-bit for now
- sBitsPerPixel = (**devicePixMap).pixelSize;
- if (sBitsPerPixel != 8)
- return false;
-
- // Stash away some information about the device
- sDeviceRect = sRealDeviceRect = (**devicePixMap).bounds;
-
- // We don't support less than 640x480
- if (sDeviceRect.right - sDeviceRect.left < 640 || sDeviceRect.bottom - sDeviceRect.top < 480)
- return false;
-
- sDeviceBasePtr = sRealDeviceBasePtr = (**devicePixMap).baseAddr;
- sDeviceRowBytes = (**devicePixMap).rowBytes & 0x3FFF;
-
- // Hide the cursor so we don't draw over it
- HideCursor();
-
- return true;
- }
-
-
- /*--------------------------------------------------------
- LoadResources
-
- Loads our resources into the system heap, then locks
- them down so they don't move in the heap. We need to
- be able to access these resources from interrupt time.
- --------------------------------------------------------*/
-
- void
- LoadResources(void)
- {
- SInt16 scrnWidth;
- SInt16 scrnHeight;
-
- scrnWidth = sDeviceRect.right - sDeviceRect.left;
- scrnHeight = sDeviceRect.bottom - sDeviceRect.top;
-
- // Make common screen sizes fit our constraints
- if (scrnWidth >= 3 * 320 && scrnHeight >= 2 * 384)
- {
- sHScale = 3;
- sVScale = 2;
- sPictWidth = sHScale * 320;
- sPictHeight = sVScale * 384;
- sWin95SplashScreen = Get1Resource('SCRN', 128);
- }
- else if (scrnWidth >= 400 * 2 && scrnHeight >= 2 * 300)
- {
- sHScale = 2;
- sVScale = 2;
- sPictWidth = sHScale * 400;
- sPictHeight = sVScale * 300;
- sWin95SplashScreen = Get1Resource('SCRN', 129);
- }
- else
- {
- sHScale = 2;
- sVScale = 2;
- sPictWidth = sHScale * 320;
- sPictHeight = sVScale * 240;
- sWin95SplashScreen = Get1Resource('SCRN', 130);
- }
-
- // Adjust the device rect
- sDeviceRect.left += (scrnWidth - sPictWidth) / 2;
- sDeviceRect.right -= (scrnWidth - sPictWidth) / 2;
- sDeviceRect.top += (scrnHeight - sPictHeight) / 2;
- sDeviceRect.bottom -= (scrnHeight - sPictHeight) / 2;
- sDeviceBasePtr += (scrnWidth - sPictWidth) / 2 +
- (scrnHeight - sPictHeight) * sDeviceRowBytes;
- if (sWin95SplashScreen == NULL)
- DebugStr("\pCouldn't load splash screen");
-
- sTotalTextColumns = (sDeviceRect.right - sDeviceRect.left) / kTextCellHSize;
- sTotalTextRows = (sDeviceRect.bottom - sDeviceRect.top) / kTextCellVSize;
-
- sWin95Colors = Get1Resource('SPLT', 128);
- if (sWin95Colors == NULL)
- DebugStr("\pCouldn't load color palette");
-
- sPCFont = Get1Resource('Font', 128);
- if (sPCFont == NULL)
- DebugStr("\pCouldn't load font bitmap");
-
- sWin95BootSound = Get1Resource('snd ', 128);
- if (sWin95BootSound == NULL)
- DebugStr("\pCouldn't load boot sound");
-
- DetachResource(sWin95SplashScreen);
- MoveHHi(sWin95SplashScreen);
- HLock(sWin95SplashScreen);
-
- DetachResource(sWin95Colors);
- MoveHHi(sWin95Colors);
- HLock(sWin95Colors);
-
- DetachResource(sPCFont);
- MoveHHi(sPCFont);
- HLock(sPCFont);
-
- DetachResource(sWin95BootSound);
- MoveHHi(sWin95BootSound);
- HLock(sWin95BootSound);
-
- DoBillGatesAnimation();
-
- if (sWin95Colors != NULL)
- {
- // Set up our palette for correct colors
- SetGDevice(sMainDevice);
-
- // Turn our patch off momentarily so it takes effect
- SetEntries(0, 255, (ColorSpec*)*sWin95Colors);
- }
- }
-
-
- /*--------------------------------------------------------
- ApplyPatches
-
- We need to prevent other INITs from drawing to the
- screen (that would spoil the effect).
- --------------------------------------------------------*/
-
- void
- ApplyPatches(void)
- {
- PixMapHandle devicePixMap;
-
- devicePixMap = (**sMainDevice).gdPMap;
- if (devicePixMap == NULL)
- return;
-
- // Point the base address of the main device
- // to ROM so pixels are dropped in the bit bucket.
- // Leave some slop to work around QD bugs.
- (**devicePixMap).baseAddr = LMGetROMBase() + 1024;
-
- sOriginalLaunch = GetToolTrapAddress(_Launch);
- SetToolTrapAddress(&sLaunchRD, _Launch);
-
- sOriginalDMB = GetToolTrapAddress(_DrawMenuBar);
- SetToolTrapAddress(&sDMBRD, _DrawMenuBar);
-
- sOriginalSetEntries = GetToolTrapAddress(_SetEntries);
- SetToolTrapAddress(&sSetEntriesRD, _SetEntries);
- }
-
-
- /*--------------------------------------------------------
- InstallVBL
-
- Installs a VBL task we use to drive the animation
- throughout the boot process.
- --------------------------------------------------------*/
-
- void
- InstallVBL(void)
- {
- sVBLTask.qLink = NULL;
- sVBLTask.qType = vType;
- sVBLTask.vblAddr = &sVBLRD;
- sVBLTask.vblCount = 1;
- sVBLTask.vblPhase = 0;
- VInstall((QElemPtr)&sVBLTask);
- }
-
-
- /*--------------------------------------------------------
- DrawWin95SplashScreen
-
- Draws the Win95 splash screen directly to the main
- device.
- --------------------------------------------------------*/
-
- void
- DrawWin95SplashScreen(void)
- {
- UInt8* curSrcPixel;
- UInt8* curDestRow;
- UInt8* curDestPixel;
- UInt16 curRow;
- UInt16 curCol;
-
- if (sWin95SplashScreen == NULL)
- return;
-
- curSrcPixel = (UInt8*)*sWin95SplashScreen;
- curDestPixel = curDestRow = (UInt8*)sDeviceBasePtr;
-
- for (curRow = 0; curRow < sPictHeight - kProgressBarHeight; curRow += sVScale)
- {
- for (curCol = 0; curCol < sPictWidth; curCol += sHScale)
- {
- UInt16 pixel;
-
- pixel = *curSrcPixel++;
-
- if (sHScale == 3)
- {
- // Pixel double in vertical direction, pixel triple in horizontal
- curDestPixel[0] = pixel;
- curDestPixel[1] = pixel;
- curDestPixel[2] = pixel;
- curDestPixel[0 + sDeviceRowBytes] = pixel;
- curDestPixel[1 + sDeviceRowBytes] = pixel;
- curDestPixel[2 + sDeviceRowBytes] = pixel;
- }
- else
- {
- // Pixel double in vertical direction, pixel double in horizontal
- curDestPixel[0] = pixel;
- curDestPixel[1] = pixel;
- curDestPixel[0 + sDeviceRowBytes] = pixel;
- curDestPixel[1 + sDeviceRowBytes] = pixel;
- }
-
- curDestPixel += sHScale;
- }
-
- curDestRow += sDeviceRowBytes * sVScale;
- curDestPixel = curDestRow;
- }
- }
-
-
- /*--------------------------------------------------------
- DrawWin95ProgressBar
-
- Draws the Win95 progress bar on the bottom of the
- screen.
- --------------------------------------------------------*/
-
- void
- DrawWin95ProgressBar(UInt8 inCurStage)
- {
- UInt8* curDestRow;
- UInt8* curDestPixel;
- UInt16 curRow;
- UInt16 curCol;
-
- curDestPixel = curDestRow = (UInt8*)sDeviceBasePtr +
- sDeviceRowBytes * (sPictHeight - kProgressBarHeight);
-
- for (curRow = sPictHeight - kProgressBarHeight; curRow < sPictHeight; curRow++)
- {
- for (curCol = 0; curCol < sPictWidth; curCol += 4)
- {
- UInt32 pixel;
-
- // Determine which color index to use. Our color
- // ramp is 0xF7 to 0xFD.
- pixel = (curCol / (sPictWidth / 16)) + inCurStage;
- if (pixel > 15)
- pixel -= 16;
- if (pixel > 7)
- pixel = 15 - pixel;
- pixel += 0xF7;
-
- pixel = (pixel << 24) + (pixel << 16) + (pixel << 8) + pixel;
-
- *(UInt32*)curDestPixel = pixel;
- curDestPixel += 4;
- }
-
- curDestRow += sDeviceRowBytes;
- curDestPixel = curDestRow;
- }
- }
-
-
- /*--------------------------------------------------------
- DrawDOSText
-
- Draws the specified text at the h/v coordinate using
- DOS characters. The coordinate is in text coordinates,
- so 0,0 is the top, left-most cell on the screen.
- --------------------------------------------------------*/
-
- void
- DrawDOSText(UInt16 inHPos, UInt16 inVPos, StringPtr inString, Boolean inInvert)
- {
- UInt16 curCharIndex;
- UInt8* curSrcRow;
- UInt8* curSrcPixel;
- UInt8* curDestRow;
- UInt8* curDestPixel;
- UInt16 curRow;
- UInt16 curCol;
- UInt8 curChar;
- UInt8 invertMask;
-
- // Multiply by the cell size (accounting for pixel doubling)
- inHPos *= kTextCellHSize;
- inVPos *= kTextCellVSize;
-
- invertMask = inInvert ? 0xFF : 0x00;
-
- for (curCharIndex = 0; curCharIndex < inString[0]; curCharIndex++)
- {
- curChar = inString[curCharIndex + 1];
-
- // Determine source pointer to font graphic data
- curSrcPixel = curSrcRow = (curChar - '!') * kTextCellHSize + (UInt8*)*sPCFont;
-
- // Determine destination location in video buffer
- curDestPixel = curDestRow = (UInt8*)sDeviceBasePtr +
- sDeviceRowBytes * (UInt32)inVPos + inHPos;
-
- // We only have graphic information for characters in this range
- if (curChar == ' ' || (curChar >= '!' && curChar <= '~'))
- {
- for (curRow = 0; curRow < kTextCellVSize; curRow++)
- {
- if (curChar == ' ')
- {
- // For a space, clear the entire box
- for (curCol = 0; curCol < kTextCellHSize; curCol++)
- *curDestPixel++ = (0xFF ^ invertMask);
- }
- else
- {
- for (curCol = 0; curCol < kTextCellHSize; curCol++)
- *curDestPixel++ = (-*curSrcPixel++) ^ invertMask;
- }
-
- curDestRow += sDeviceRowBytes;
- curDestPixel = curDestRow;
- curSrcRow += ('~' - '!' + 1) * kTextCellHSize;
- curSrcPixel = curSrcRow;
- }
- }
-
- inHPos += kTextCellHSize;
- }
- }
-
-
- /*--------------------------------------------------------
- VBLDrawProc
-
- This is the VBL procedure that determines which state
- we're in currently and calls the correct drawing
- routine.
- --------------------------------------------------------*/
-
- void
- VBLDrawProc(VBLTaskPtr vblTaskPtr)
- {
- #pragma unused (vblTaskPtr)
- UInt32 curTicks;
- Str255 processorString;
- Str63 newInitName;
- char initChar;
-
- curTicks = LMGetTicks();
-
- if (curTicks >= sNextStateChangeTicks)
- {
- switch (sCurrentDrawState)
- {
- case kDrawBIOSMessage:
- // Draw the BIOS text
- DrawDOSText(1, sCurTextRow, "\pMacOS Toolbox BIOS", false);
- DrawDOSText(sTotalTextColumns - 34, sCurTextRow++,
- "\p(C) Apple Computer, Inc. 1984-97", false);
- GetProcessorString(processorString);
- DrawDOSText(1, sCurTextRow, processorString, false);
-
- // Progress to the next state after several ticks
- sNextStateChangeTicks = curTicks + 10;
- sCurrentDrawState = kDrawMemorySize;
- sCurrentDrawSubState = 0;
- break;
-
- case kDrawMemorySize:
- if (DoMemoryTest())
- {
- // Progress to the next state after several ticks
- sCurrentDrawState = kDrawStartingOS;
- sNextStateChangeTicks = curTicks + 60;
- }
- else
- {
- // If we are not done testing memory, keep
- // going in this state for a while
- sNextStateChangeTicks = curTicks + 2;
- }
- break;
-
- case kDrawStartingOS:
- sCurTextRow += 6;
- DrawDOSText(1, sCurTextRow, "\pStarting MacOS 8.0...", false);
-
- // Progress to the next state almost immediately
- sCurrentDrawState = kDrawCDDriverText;
- sNextStateChangeTicks = curTicks + 20;
- sCurrentDrawSubState = 15;
- sCurTextRow += 2;
- break;
-
- case kDrawCDDriverText:
- DrawDOSText(1, sCurTextRow, "\pApple CD-ROM Driver, Version 8.0 (SCSI001)", false);
- DrawDOSText(1, sCurTextRow + 1, "\pLooking for CD-ROM Drive", (sCurrentDrawSubState & 0x1) == 0);
-
- if (--sCurrentDrawSubState == 0)
- {
- // Progress to the next state after a while
- DrawDOSText(1, sCurTextRow + 1, "\pCD-ROM Drive Detected ", false);
- sCurrentDrawState = kMouseDriverText;
- sCurTextRow += 3;
- }
- else
- {
- sNextStateChangeTicks = curTicks + 20;
- }
- break;
-
- case kMouseDriverText:
- DrawDOSText(1, sCurTextRow++, "\pMacOS Mouse Driver 8.0", false);
- DrawDOSText(1, sCurTextRow++, "\pCopyright (C) Apple Computer, Inc. 1984-97", false);
- DrawDOSText(1, sCurTextRow++, "\pStandard ADB Mouse Detected", false);
- sCurTextRow++;
- sCurrentDrawState = kBlinkCursor;
- sNextStateChangeTicks = curTicks + 30;
- sCurrentDrawSubState = 50000;
- break;
-
- case kBlinkCursor:
- // Has a new INIT been loaded since last time?
- if (HasNewInitName(newInitName))
- {
- DrawDOSText(1, sCurTextRow, "\p ", false);
- DrawNewInitName(newInitName);
-
- if (sCurTextRow > sTotalTextRows - 4)
- ScrollTextScreen(2);
- else
- sCurTextRow += 2;
-
- // This is really gross, but if the current INIT
- // name is beyond the a certain point, we'll continue.
- initChar = ((sLastInitName >> 16) & 0xFF);
- if (initChar > 'a')
- initChar -= 'a' - 'A';
- if (initChar > 'S')
- sCurrentDrawState = kDrawWin95Screen;
- }
-
- // Blink the cursor every 8th time
- if ((sCurrentDrawSubState % 8) == 0)
- {
- if ((sCurrentDrawSubState % 16) == 0)
- DrawDOSText(1, sCurTextRow, "\p_", false);
- else
- DrawDOSText(1, sCurTextRow, "\p ", false);
- }
-
- if (--sCurrentDrawSubState == 0)
- sCurrentDrawState = kDrawWin95Screen;
- break;
-
- case kDrawWin95Screen:
- DrawWin95SplashScreen();
-
- // Progress to the next state immediately
- sCurrentDrawState = kAnimateWin95Screen;
- sCurrentDrawSubState = 0;
- break;
-
- case kAnimateWin95Screen:
- DrawWin95ProgressBar(sCurrentDrawSubState);
-
- // Keep animating every few ticks
- sNextStateChangeTicks = curTicks + 6;
- sCurrentDrawSubState++;
- if (sCurrentDrawSubState > 15)
- sCurrentDrawSubState = 0;
- break;
-
- }
- }
-
- // Reprime the VBL task so we are called back again
- sVBLTask.vblCount = 1;
- }
-
-
- /*--------------------------------------------------------
- DoMemoryTest
-
- Draws the memory test text to the DOS screen. Returns
- true once the memory test is complete.
- --------------------------------------------------------*/
-
- Boolean
- DoMemoryTest(void)
- {
- Str31 memorySizeText;
- UInt16 curCharIndex;
- UInt32 memorySize;
-
- // Clear out the string
- for (curCharIndex = 0; curCharIndex < 10; curCharIndex++)
- memorySizeText[curCharIndex] = ' ';
-
- // Construct the memory size string
- memorySizeText[9] = 'K';
- memorySizeText[0] = 9;
-
- memorySize = sCurrentDrawSubState;
-
- for (curCharIndex = 8; curCharIndex > 0; curCharIndex--)
- {
- memorySizeText[curCharIndex] = (memorySize % 10) + '0';
-
- memorySize /= 10;
- if (memorySize == 0)
- break;
- }
-
- // Draw the new text
- DrawDOSText(1, 4, memorySizeText, false);
-
- // Add one megabyte (1024Kb) to the state
- sCurrentDrawSubState += 1024;
-
- // Did we report all the memory?
- return (sCurrentDrawSubState > sMachineMemory);
- }
-
-
- /*--------------------------------------------------------
- TearDownHacks
-
- Removes the VBL task, patches, etc.
- --------------------------------------------------------*/
-
- void
- TearDownHacks(void)
- {
- PixMapHandle devicePixMap;
-
- // Restore the real base address of the main device
- devicePixMap = (**sMainDevice).gdPMap;
- if (devicePixMap == NULL)
- return;
-
- (**devicePixMap).baseAddr = sRealDeviceBasePtr;
-
- VRemove((QElemPtr)&sVBLTask);
-
- RestoreDeviceClut(sMainDevice);
- sSetEntriesPatchActive = false;
- ShowCursor();
- }
-
-
- /*--------------------------------------------------------
- PlayWin95StartSound
-
- Plays the Win95 start wound asynchronously.
- --------------------------------------------------------*/
-
- void
- PlayWin95StartSound(void)
- {
- if (sSoundChannel != NULL)
- (void) SndPlay(sSoundChannel, (SndListHandle)sWin95BootSound, true);
- }
-
-
- /*--------------------------------------------------------
- GetProcessorString
-
- Returns an ASCII string that describes the speed
- and type of processor.
- --------------------------------------------------------*/
-
- void
- GetProcessorString(Str255 outProcString)
- {
- UInt32 mhz;
-
- outProcString[0] = 3;
- outProcString[1] = ' ';
- outProcString[2] = ' ';
-
- // Convert speed from Hz to MHz (rounding if necessary)
- mhz = (sMachineSpeed + 500000L) / 1000000L;
-
- outProcString[3] = (mhz % 10) + '0';
- mhz /= 10;
- if (mhz > 0)
- outProcString[2] = (mhz % 10) + '0';
- mhz /= 10;
- if (mhz > 0)
- outProcString[1] = (mhz % 10) + '0';
-
- AppendPString(outProcString, "\pMHz ");
-
- switch (sMachineType)
- {
- case gestaltCPU601:
- AppendPString(outProcString, "\pPowerPC 601");
- break;
-
- case gestaltCPU603:
- AppendPString(outProcString, "\pPowerPC 603");
- break;
-
- case gestaltCPU604:
- AppendPString(outProcString, "\pPowerPC 604");
- break;
-
- case 0x106:
- AppendPString(outProcString, "\pPowerPC 603e");
- break;
-
- case 0x107:
- AppendPString(outProcString, "\pPowerPC 603ev");
- break;
-
- case 0x108:
- AppendPString(outProcString, "\pPowerPC 740");
- break;
-
- case 0x109:
- AppendPString(outProcString, "\pPowerPC 604e");
- break;
-
- case 0x10A:
- AppendPString(outProcString, "\pPowerPC 760");
- break;
-
- default:
- AppendPString(outProcString, "\pUnknown Processor");
- break;
- }
- }
-
-
- /*--------------------------------------------------------
- AppendPString
-
- Appends one pascal string onto a second.
- --------------------------------------------------------*/
-
- void
- AppendPString(StringPtr ioStrA, StringPtr ioStrB)
- {
- UInt16 curStrIndex;
-
- for (curStrIndex = 0; curStrIndex < ioStrB[0]; curStrIndex++)
- ioStrA[ioStrA[0] + curStrIndex + 1] = ioStrB[curStrIndex + 1];
-
- ioStrA[0] += ioStrB[0];
- }
-
-
- /*--------------------------------------------------------
- LaunchPatchProc
-
- Patch for the _Launch trap.
- --------------------------------------------------------*/
-
- pascal OSErr
- LaunchPatchProc(LaunchPBPtr launchParams)
- {
- OSErr tempErr;
-
- // Disable ourselves now
- if (sLaunchPatchActive)
- {
- THz oldZone;
-
- oldZone = GetZone();
- SetZone(SystemZone());
-
- // Allocate a sound channel so we can call the start sound
- (void) SndNewChannel(&sSoundChannel, squareWaveSynth, 0, NULL);
-
- SetZone(oldZone);
-
- PlayWin95StartSound();
- }
-
- sLaunchPatchActive = false;
-
- // Chain through to the caller
- tempErr = CallUniversalProc((UniversalProcPtr)sOriginalLaunch,
- kPascalStackBased | RESULT_SIZE(kTwoByteCode) | STACK_ROUTINE_PARAMETER(1, kFourByteCode),
- launchParams);
-
- return tempErr;
- }
-
-
- /*--------------------------------------------------------
- DMBPatchProc
-
- Patch for the _DrawMenuBar trap.
- --------------------------------------------------------*/
-
- pascal void
- DMBPatchProc(void)
- {
- // Disable ourselves now
- if (!sLaunchPatchActive && sDMBPatchActive)
- {
- TearDownHacks();
- sDMBPatchActive = false;
- }
-
- // Chain through to the caller
- (void) CallUniversalProc((UniversalProcPtr)sOriginalDMB, kPascalStackBased);
- }
-
-
- /*--------------------------------------------------------
- SetEntriesPatch
-
- Prevents the system from taking over the clut while
- we're installed
- --------------------------------------------------------*/
-
- pascal void
- SetEntriesPatch(short start, short count, CSpecArray aTable)
- {
- if (!sSetEntriesPatchActive)
- {
- // Call through to original
- (void) CallUniversalProc((UniversalProcPtr)sOriginalSetEntries,
- kPascalStackBased |
- STACK_ROUTINE_PARAMETER(1, kTwoByteCode) |
- STACK_ROUTINE_PARAMETER(2, kTwoByteCode) |
- STACK_ROUTINE_PARAMETER(3, kFourByteCode),
- start,
- count,
- aTable);
- }
- }
-
-
- /*--------------------------------------------------------
- HasNewInitName
-
- Determines whether there is a new INIT loading
- since the last time we checked. If a new INIT is
- being loaded since the last time we were called,
- we return true.
- --------------------------------------------------------*/
-
- Boolean
- HasNewInitName(Str63 outInitName)
- {
- StringPtr curInitName;
- UInt16 curChar;
- Boolean initChanged = false;
-
- curInitName = *(StringPtr*)0x914;
-
- // Make sure there is a valid INIT name hanging off of 0x914
- if (*(UInt32*)0x910 == 0xFFFFFFFF &&
- (UInt32)curInitName != 0xFFFFFFFF &&
- ((UInt32)curInitName & 0x3) == 0 &&
- (SInt32)curInitName > 0)
- {
- curInitName = *(StringPtr*)0x914;
-
- if (curInitName[0] >= 4 && sLastInitName != *(UInt32*)curInitName)
- {
- // Copy the current INIT name to our output. Since we're
- // being called at interrupt time, it's possible the name
- // is only partially copied, but it's most likely intact.
- for (curChar = 0; curChar <= curInitName[0]; curChar++)
- outInitName[curChar] = curInitName[curChar];
-
- // Record the first four bytes so we can tell when it changes
- sLastInitName = *(UInt32*)curInitName;
- initChanged = true;
- }
- }
-
- return initChanged;
- }
-
-
- /*--------------------------------------------------------
- DrawNewInitName
-
- Outputs a message at the current line describing
- the INIT being loaded.
- --------------------------------------------------------*/
-
- void
- DrawNewInitName(Str63 inInitName)
- {
- DrawDOSText(1, sCurTextRow, "\pLoading driver ", false);
- DrawDOSText(16, sCurTextRow, inInitName, false);
- }
-
-
- /*--------------------------------------------------------
- ScrollTextScreen
-
- Scrolls the entire text buffer up the specified
- number of rows.
- --------------------------------------------------------*/
-
- void
- ScrollTextScreen(UInt16 inRows)
- {
- UInt32* curSrc;
- UInt32* curDest;
- UInt32* curSrcRow;
- UInt32* curDestRow;
- UInt16 curColumn;
- UInt16 curRow;
-
- curSrcRow = curSrc = (UInt32*)(sDeviceBasePtr + sDeviceRowBytes * inRows * kTextCellVSize);
- curDestRow = curDest = (UInt32*)sDeviceBasePtr;
-
- for (curRow = 0; curRow < sTotalTextRows * kTextCellVSize; curRow++)
- {
- if (curRow >= (sTotalTextRows - inRows) * kTextCellVSize)
- {
- // Fill in last few rows with black
- for (curColumn = 0; curColumn < sTotalTextColumns * kTextCellHSize; curColumn += 4)
- *curDest++ = 0xFFFFFFFF;
- }
- else
- {
- for (curColumn = 0; curColumn < sTotalTextColumns * kTextCellHSize; curColumn += 4)
- *curDest++ = *curSrc++;
- }
-
- curSrcRow = (UInt32*)((UInt8*)curSrcRow + sDeviceRowBytes);
- curDestRow = (UInt32*)((UInt8*)curDestRow + sDeviceRowBytes);
- curSrc = curSrcRow;
- curDest = curDestRow;
- }
- }
-
-
- /*--------------------------------------------------------
- DoBillGatesAnimation
-
- Scrolls the Mac screen off to the right while Bill
- Gates pushes it.
- --------------------------------------------------------*/
-
- void
- DoBillGatesAnimation(void)
- {
- GDHandle savedGD;
- CGrafPtr savedPort;
- CGrafPtr wMgrPort;
- Rect curRect;
- Rect billRect;
- Rect billEraseRect;
- UInt32 lastTicks;
- RgnHandle dummyRgn;
- PicHandle billPict1;
- PicHandle billPict2;
- PicHandle billPict3;
- PicHandle curBillPict;
- UInt8 curStage = 0;
- UInt32 scrnWidth;
- UInt8 bobStep = 0;
-
- billPict1 = GetPicture(128);
- billPict2 = GetPicture(129);
- billPict3 = GetPicture(130);
- curBillPict = billPict1;
-
- billRect = (*billPict1)->picFrame;
- OffsetRect(&billRect, -billRect.right, -billRect.bottom + sRealDeviceRect.bottom);
- billEraseRect = billRect;
- billEraseRect.right = billEraseRect.left;
- billEraseRect.left = billEraseRect.right - kBillScrollAmount - 4;
-
- GetGWorld(&savedPort, &savedGD);
- GetCWMgrPort(&wMgrPort);
- SetGWorld(wMgrPort, sMainDevice);
-
- // Fill in background with black
- BackColor(blackColor);
- curRect = sRealDeviceRect;
- lastTicks = TickCount();
- dummyRgn = NewRgn();
-
- scrnWidth = sRealDeviceRect.right - sRealDeviceRect.left;
-
- while (billRect.left < curRect.right)
- {
- ScrollRect(&curRect, kBillScrollAmount, 0, dummyRgn);
- DrawPicture(curBillPict, &billRect);
- EraseRect(&billEraseRect);
-
- OffsetRect(&billRect, kBillScrollAmount, bobStep >= 4 ? -2 : 2);
- billEraseRect.right += kBillScrollAmount;
- curRect.left += kBillScrollAmount;
- bobStep++;
- if (bobStep >= 8)
- bobStep = 0;
-
- // Add a small delay so we don't move too fast
- while (TickCount() <= lastTicks + 2) {};
- lastTicks = TickCount();
-
- switch (curStage)
- {
- case 0:
- if (curRect.left >= 6 * scrnWidth / 10)
- {
- curBillPict = billPict2;
- curStage++;
- }
- break;
-
- case 1:
- if (curRect.left >= 7 * scrnWidth / 10)
- {
- curBillPict = billPict3;
- curStage++;
- }
- break;
-
- case 2:
- if (curRect.left >= 8 * scrnWidth / 10)
- {
- curBillPict = billPict2;
- curStage++;
- }
- break;
-
- case 3:
- if (curRect.left >= 9 * scrnWidth / 10)
- {
- curBillPict = billPict1;
- curStage++;
- }
- break;
- }
- }
-
- EraseRect(&sRealDeviceRect);
- DisposeRgn(dummyRgn);
- SetGWorld(savedPort, savedGD);
- }
-
-
-
-
-